const { PACKAGE_PATHS } = require('./configuration');
const path = require('path');
const fs = require('fs').promises;
const { exec } = require('child_process')
const _ = require('lodash')

const readPackageJson = async (index) => {
  try {
    const partialPath = PACKAGE_PATHS[index]
    const contents = await fs.readFile(path.join(partialPath))
    return JSON.parse(contents.toString())
  } catch (error) { }
}

const clear = () => console.clear()

const execListen = (data) => {
  return new Promise((resolve, reject) => {
    let command = data
    if (data instanceof Array) {
      command = _.join(data, " ")
    }
    const child = exec(command, (error, stdout) => {
      if (error) {
        reject(error);
        return;
      }
      resolve(stdout);
    })
    child.stdout.on('data', (data) => console.log(data))
  });
}

const mkdirsRecursion = async (dirname, callback) => {
  let err = await fs.access(dirname)
  if (err) {
    await mkdirsRecursion(path.dirname(dirname), async () => {
      await fs.mkdir(dirname)
      if (callback) {
        await callback()
      }
    });
  } else {
    if (callback) {
      await callback()
    }
  }
}

const writeFile = async (dirname, content) => {
  try {
    await mkdirsRecursion(path.join(dirname, "../"))
    await fs.writeFile(dirname, content)
  } catch (error) {
    console.log(error)
  }
};

const createStartBat = async () => {
  const runPath = path.join(__dirname, "../../")
  const driveLetter = String(runPath[0]).toLowerCase()
  const outputFilePath = path.join(runPath, "start.bat")
  const template = `@echo off\ncd /${driveLetter} ${runPath}\necho "${runPath}"\ncall yarn start\npause`
  await writeFile(outputFilePath, template, true)
}

function logBright(loggable) {
  console.log(`\x1b[1m${loggable}\x1b[0m`);
}

const updateElectronPkg = async (data, dist, output) => {
  // 启动地址获取绝对地址
  const runPath = path.resolve(PACKAGE_PATHS[0], "../")
  const electronPath = path.resolve(PACKAGE_PATHS[3], "../")
  const distPath = path.join(runPath, dist)
  const distFilePath = path.join(distPath, "./server/main.js")
  const mainFilePath = path.relative(electronPath, distFilePath).replaceAll("\\", "/")
  _.set(data, "main", mainFilePath)
  const electronPathRelative = path.relative(electronPath, distPath)
  const matchPath = path.join(electronPathRelative, "./**/*").replaceAll("\\", "/")
  let files = _.get(data, "build.files")
  _.set(data, "build.files", _.uniq([matchPath].concat(files)))
  if (typeof output === "string") {
    const outputPath = path.join(runPath, output)
    _.set(data, "build.directories.output", path.relative(electronPath, outputPath).replaceAll("\\", "/"))
  }
  await writeFile(path.join(runPath, PACKAGE_PATHS[3]), JSON.stringify(data, null, 2))
}

const updateElectronTsPkg = async (data, outDir) => {
  const runPath = path.join(__dirname, "../../")
  const electronTsPath = path.join(PACKAGE_PATHS[2], "../")
  const outputPath = path.join(runPath, outDir)
  const mainPath = path.join(path.relative(electronTsPath, outputPath), "./server").replaceAll("\\", "/")
  console.log("electronTsPath", mainPath)
  data["compilerOptions"]["outDir"] = mainPath
  await writeFile(path.join(runPath, PACKAGE_PATHS[2]), JSON.stringify(data, null, 2))
}

module.exports = {
  readPackageJson,
  clear,
  execListen,
  createStartBat,
  updateElectronPkg,
  updateElectronTsPkg,
  logBright,
  writeFile
}